﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace Comp376A2_9609695
{
    /// <summary>
    /// The Fygar monster. Walks around, shoots fire.
    /// </summary>
    public class Fygar : Monster, Drawable
    {
        public SpriteSheet spritesheet;
        private bool breathingFire = false;
        private int fireTime;
        private int fireDelay;
        private String animName;
        private List<int> animFrames;
        private int frame;
        private int frameTime;
        private int frameLength;
        private Fire fire;
        private Random r;
        
        public String animation
        {
            get { return animName; }
            set
            {
                if (spritesheet.getAnimList().Contains(value))
                {
                    if (animName != value)
                    {
                        animName = value;
                        animFrames = spritesheet.getAnimation(animName);
                        frame = 0;
                        frameTime = 0;
                    }
                }
            }
        }

        public Fygar(int startX, int startY) : base (startX, startY)
        {
            // Fire has a random delay from 1 to 3 seconds
            r = new Random();
            fireDelay = r.Next(2000) + 1000;
            fireTime = 0;
            frameLength = 200;
        }

        public override void update(GameTime time, GameController control)
        {
            if (!breathingFire)
            {
                base.update(time, control);
                speed = 6 + control.currLevel * 2;
                fireTime += time.ElapsedGameTime.Milliseconds;
                // If the Fygar is being pumped, set the frame in the animation
                if (pumpLevel != 0)
                {
                    animation = "pump";
                    frame = 0;
                    if (pumpLevel > 1)
                        frame = 1;
                    if (pumpLevel > 3)
                        frame = 2;
                    if (pumpLevel > 6)
                        frame = 3;
                }
                // If the Fygar is a ghost, the fire timer isn't reset completely.
                else if (ghosting)
                {
                    animation = "ghost";
                    fireTime = fireTime % 1000;
                }
                else
                    animation = "walk";

                // If the Fygar isn't already breathing fire, isn't being pumped, is fully in a cell and is facing left or right, breath fire
                if (!breathingFire && fireTime >= fireDelay 
                    && (facing == Direction.Left || facing == Direction.Right) 
                    && Math.Floor(position.X - control.level.X) % 16 == 0 
                    && pumpLevel == 0)
                {
                    Vector2 gridPos = control.level.getGridPos((int)(position.X - control.level.X), (int)(position.Y - control.level.Y));
                    Vector2 pgridPos = control.level.getGridPos((int)(control.player.position.X - control.level.X), (int)(control.player.position.Y - control.level.Y));
                    // Only breath fire if the Fygar is facing the player
                    if (((facing == Direction.Left && gridPos.X > pgridPos.X) ||
                    (facing == Direction.Right && gridPos.X < pgridPos.X)))
                    {
                        breathingFire = true;
                        fireTime = 500; // There is a half second delay before the actual fire appears
                        animation = "fire";
                    }
                    else
                    {
                        // If the Fygar isn't facing the player the timer isn't reset completely
                        fireTime = fireDelay/2;
                    }
                }
            }
            else if (!squished)
            {
                fireTime += elapsed;
                // a half second has passed, create the fire and play the sound
                if (null == fire && fireTime >= 1000)
                {
                    if (!soundCue.IsPlaying)
                    {
                        if (!soundCue.IsPrepared)
                            soundCue = bank.GetCue("fygarfire");
                        else
                        {
                            soundCue.Play();
                        }
                    }
                    fire = new Fire(
                        (int)position.X + (facing == Direction.Right ? 16 : 0),
                        (int)position.Y,
                        facing == Direction.Right);
                    fire.spritesheet = spritesheet;
                    fire.animation = "flame";
                    if (control.level.getCellAt((int)fire.position.X - control.level.X, (int)fire.position.Y - control.level.Y) != 0)
                        control.addObject(fire);
                    else
                    {
                        fire = null;
                        breathingFire = false;
                        fireTime = 0;
                        fireDelay = r.Next(2000) + 1000;
                        ghostTimer = 2000;
                        soundCue = bank.GetCue("pump");
                    }

                }
                // When the fire is gone, go back to normal
                if (null != fire && fire.isDead)
                {
                    fire = null;
                    breathingFire = false;
                    fireTime = 0;
                    fireDelay = r.Next(2000) + 1000;
                    ghostTimer = 2000;
                    soundCue = bank.GetCue("pump");
                }

            }
            frameTime += elapsed;
            if (frameTime >= frameLength && pumpLevel == 0)
            {
                frame = (frame + 1) % animFrames.Count;
                frameTime -= frameLength;
            }
        }

        public override void reset()
        {
            base.reset();
            animation = "walk";
        }

        Texture2D Drawable.getImage()
        {
            return spritesheet.image;
        }

        void Drawable.draw(SpriteBatch renderer)
        {

            Rectangle sprite = spritesheet.getSprite(animFrames.ElementAt(frame));
            // If the Fygar is squished, the image is squished
            if (squished)
            {
                Rectangle drawRect = new Rectangle((int)position.X, (int)position.Y, sprite.Width, sprite.Height);
                drawRect.Y += sprite.Height - 4;
                drawRect.Height = 4;
                renderer.Draw(spritesheet.image, drawRect, sprite, Color.White);
            }
            else
            {
                Vector2 drawPos = new Vector2(position.X, position.Y);
                if (pumpLevel > 0)
                    drawPos.Y -= 7;
                if (facing == Direction.Right)
                {
                    renderer.Draw(spritesheet.image, drawPos, sprite, Color.White, 0f, new Vector2(), 1f, SpriteEffects.FlipHorizontally, 0);
                }
                else
                    renderer.Draw(spritesheet.image, drawPos, sprite, Color.White);
            }
        }

        public override bool collides(Rectangle box, bool pumping = false)
        {
            // Don't collide if the Fygar is a ghost or being pumped. Always collide if DigDug is pumping
            if ((ghosting || pumpLevel != 0) && !pumping)
                return false;
            else
            {
                Rectangle bounds = new Rectangle((int)position.X + 2, (int)position.Y + 2, 13, 13);
                Rectangle intersection = new Rectangle();
                Rectangle.Intersect(ref box, ref bounds, out intersection);
                return (intersection.Width != 0 && intersection.Height != 0);
            }
        }
    }
}
